/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       ownable_event.cpp

	$Header: /game/ownable_event.cpp $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "ownable_event.h"

#include "bitset_io.h"
#include "player.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

// --------------------------------------------------------------------------
// Unnamed namespace
// --------------------------------------------------------------------------

namespace
{

	int const k_current_built_in_event_map_format_version = 0;
	int const k_current_timed_event_map_format_version = 0;
	int const k_current_triggerable_event_map_format_version = 0;
	int const k_current_continuous_event_map_format_version = 0;

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_built_in_event_special_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_built_in_event_standard_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_timed_event_special_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_timed_event_standard_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_triggerable_event_special_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_triggerable_event_standard_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_continuous_event_special_base_map_format_version( int format_version )
	{
		return 0;
	}

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	inline int to_continuous_event_standard_base_map_format_version( int format_version )
	{
		return 0;
	}

} // Unnamed namespace

// --------------------------------------------------------------------------
// t_ownable_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_event::ownership_test(t_player const* player) const
{
	if (!player)
		return m_owner_color_mask.test(k_player_gray);

	if (player->is_computer()) {
		if (!m_run_for_computer_owners)
			return false;
	} else
		if (!m_run_for_human_owners)
			return false;
	
	return m_owner_color_mask.test(player->get_color());
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_event::read(
	std::streambuf &	stream,
	int					format_version )
{
	m_owner_color_mask = get_bitset< k_player_color_count >( stream );
	m_run_for_human_owners = get< t_int8 >( stream ) != 0;
	m_run_for_computer_owners = get< t_int8 >( stream ) != 0;
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_event::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	m_owner_color_mask = get_bitset< k_player_color_count >( stream );

	std::bitset< 2 > owner_type_mask = get_bitset< 2 >( stream );
	m_run_for_human_owners = owner_type_mask[ 0 ];
	m_run_for_computer_owners = owner_type_mask[ 1 ];

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_event::write( std::streambuf & stream ) const
{
	put_bitset( stream, m_owner_color_mask );
	put< t_int8 >( stream, m_run_for_human_owners );
	put< t_int8 >( stream, m_run_for_computer_owners );
	return true;
}

// --------------------------------------------------------------------------
// t_ownable_built_in_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_built_in_event::read_from_map( std::streambuf & stream )
{
	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_built_in_event_map_format_version )
		return false;

	return		t_discrete_event::read_from_map(
					stream,
					to_built_in_event_special_base_map_format_version( format_version ) )
			&&	t_ownable_event::read_from_map(
					stream,
					to_built_in_event_standard_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// t_ownable_timed_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_timed_event::read(
	std::streambuf &	stream,
	int					version )
{
	if (	!t_timed_event::read( stream, version )
		||	!t_ownable_event::read( stream, version ) )
		return false;

	m_execution_flag = get< t_int8 >( stream ) != 0;

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_timed_event::read_from_map( std::streambuf & stream )
{
	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_timed_event_map_format_version )
		return false;

	return		t_timed_event::read_from_map(
					stream,
					to_timed_event_special_base_map_format_version( format_version ) )
			&&	t_ownable_event::read_from_map(
					stream,
					to_timed_event_standard_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_timed_event::write( std::streambuf & stream ) const
{
	if (	!t_timed_event::write( stream )
		||	!t_ownable_event::write( stream ) )
		return false;

	put< t_int8 >( stream, m_execution_flag );

	return true;
}

// --------------------------------------------------------------------------
// t_ownable_triggerable_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_triggerable_event::read_from_map( std::streambuf & stream )
{
	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_triggerable_event_map_format_version )
		return false;

	return		t_triggerable_event::read_from_map(
					stream,
					to_triggerable_event_special_base_map_format_version( format_version ) )
			&&	t_ownable_event::read_from_map(
					stream,
					to_triggerable_event_standard_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// t_ownable_continuous_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_continuous_event::read(
	std::streambuf &	stream,
	int					version )
{
	if (	!t_continuous_event::read( stream, version )
		||	!t_ownable_event::read( stream, version ) )
		return false;

	m_run_only_during_owners_turn = get< t_int8 >( stream ) != 0;

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_continuous_event::read_from_map( std::streambuf & stream )
{
	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_continuous_event_map_format_version )
		return false;

	if (	!t_continuous_event::read_from_map(
				stream,
				to_continuous_event_special_base_map_format_version( format_version ) ) )
		return false;

	m_run_only_during_owners_turn = get< t_uint8 >( stream ) != 0;

	return	t_ownable_event::read_from_map(
				stream,
				to_continuous_event_standard_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_ownable_continuous_event::write( std::streambuf & stream ) const
{
	if (	!t_continuous_event::write( stream )
		||	!t_ownable_event::write( stream ) )
		return false;

	put< t_int8 >( stream, m_run_only_during_owners_turn );

	return true;
}


